﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using DiscoveryLogic.UI.Layouts.ContentScreens;
using DiscoveryLogic.UI.Layouts.Models;
using DiscoveryLogic.DataServices.DataSources;

namespace DiscoveryLogic.UI.Layouts.Controls
{
    public partial class PieOverlay : UserControl
    {
        #region Private Variables

            private readonly MouseManager mouseEventManager;

            private double currentAngle;
            private double totalDegrees;

            private double radius;
            private double centerX, centerY;
            private List<PieSlice> pieSliceList;

            private double totalPieAmount;
            private double totalContributionPercent;

            private string invStyleName;

            private bool isOverlapSlice;
            private int overlapSliceId;


        #endregion

        #region Constructors

            public PieOverlay(Point center, double overlayRadius)
            {
                // Required to initialize variables
                InitializeComponent();

                mouseEventManager = new MouseManager();

                pieSliceList = new List<PieSlice>();

                centerX = center.X;
                centerY = center.Y;
                radius = overlayRadius;
                currentAngle = 0;
                totalDegrees = 360;

                OverlayScaleTransform.CenterX = centerX;
                OverlayScaleTransform.CenterY = centerY;
            }

        #endregion 

        #region Helper Methods

            private Point CreateSlicePath(PieSlice s, double piePercent, double lastPercent, Point last)
            {
                bool isLargeAngle = piePercent >= 50;
                double previousAngleinRadians = lastPercent * .02 * Math.PI;
                lastPercent += piePercent;
                double currentAngleinRadians = lastPercent * .02 * Math.PI;

                double x = centerX - (radius * Math.Cos(currentAngleinRadians));
                double y = centerY - (radius * Math.Sin(currentAngleinRadians));

                // Construct slice
                PathFigure pf = new PathFigure();
                pf.StartPoint = new Point(centerX, centerY);

                LineSegment openingls = new LineSegment();
                LineSegment closingls = new LineSegment();

                openingls.Point = new Point(last.X, last.Y);
                closingls.Point = new Point(centerX, centerY);

                ArcSegment arc = new ArcSegment();
                arc.Size = new Size(radius, radius);
                arc.RotationAngle = 0;
                arc.IsLargeArc = isLargeAngle;
                arc.SweepDirection = SweepDirection.Clockwise;
                if (piePercent >= 100)
                {
                    y += 0.01;
                }
                arc.Point = new Point(x, y);

                pf.Segments = new PathSegmentCollection();
                pf.Segments.Add(openingls);
                pf.Segments.Add(arc);
                pf.Segments.Add(closingls);

                PathGeometry pg = new PathGeometry();
                pg.Figures = new PathFigureCollection();
                pg.Figures.Add(pf);

                // Create points for icon and animation
                double angleTooltip = previousAngleinRadians + (piePercent * .01 * Math.PI);
                double tooltipX = centerX - (radius * 0.9) * Math.Cos(angleTooltip);
                double tooltipY = centerY - (radius * 0.9) * Math.Sin(angleTooltip);
                double animateX = centerX - (radius * 0.1) * Math.Cos(angleTooltip);
                double animateY = centerY - (radius * 0.1) * Math.Sin(angleTooltip);

                Point toolTipPoint = new Point(tooltipX, tooltipY);
                Point animationPoint = new Point(animateX - centerX, animateY - centerY);

                // Pass into pie slice
                if (piePercent >= 100)
                {
                    s.SetSlice(pg, toolTipPoint, animationPoint, 0, new Point(centerX, centerY));
                }
                else
                {
                    s.SetSlice(pg, toolTipPoint, animationPoint, 2, new Point(centerX, centerY));
                }

                last.X = x;
                last.Y = y;

                return last;
            }

        #endregion

        #region Public Methods

            public void LowerAllSlices()
            {
                for (int i = 0; i < pieSliceList.Count; i++)
                {
                    pieSliceList[i].LowerSlice();
                }
            }

            public void ScaleOverlay(bool grow)
            {
                if (grow)
                {
                    GrowOverlay.Begin();
                }
                else
                {
                    ShrinkOverlay.Begin();
                }
            }

            public List<PieSlice> GetPieSliceList()
            {
                return pieSliceList;
            }

            public string InvStyleName
            {
                get { return invStyleName; }
                set { invStyleName = value; }
            }

            public bool FundExists(FundTypes fundType)
            {
                for (int i = 0; i < pieSliceList.Count; i++)
                {
                    if (fundType == pieSliceList[i].Fund.FundType)
                    {
                        return true;
                    }
                }

                return false;
            }

            public void HideFundIcons(bool hide)
            {
                for (int i = 0; i < pieSliceList.Count; i++)
                {
                    pieSliceList[i].HideFundIcon(hide);
                }
            }

            public void AddSlice(double amount, double percent, EnrollmentFund fund)
            {
                // Update totals
                totalPieAmount += amount;
                totalContributionPercent += percent;               

                
                // Update each slice's total amount
                foreach (PieSlice p in pieSliceList)
                {
                    p.TotalPieAmount = totalPieAmount;
                }
                

                // Create new PieSlice
                PieSlice slice = new PieSlice(amount, totalPieAmount, percent, fund);
             
                slice.Id = pieSliceList.Count;
                slice.SliceContribution = percent;

                // Add slice to list
                pieSliceList.Add(slice);

                // Add slice to canvas
                PieOverlayCanvas.Children.Add(slice);

                // Remove handlers
                slice.RemoveAllHandlers();
            }


            public void DrawSlices()
            {
                Point last = new Point(centerX - radius, centerY);
                double total = totalPieAmount;
                double lastPercent = 0.0;

                for (int j = 0; j < EnrollmentFund.numFundTypes; j++)
                {
                    for (int i = 0; i < pieSliceList.Count; i++)
                    {
                        PieSlice s = pieSliceList[i];

                        if ((int)s.Fund.FundType == j)
                        {
                            double piePercent = 100 * s.SliceAmount / total;
                            last = CreateSlicePath(s, piePercent, lastPercent, last);
                            lastPercent += piePercent;
                        }
                    }
                }
            }

            public bool HitTestHighlight(MouseEventArgs e, FundTypes fundType)
            {
                isOverlapSlice = false;

                foreach (PieSlice p in pieSliceList)
                {
                    p.ResetColor();
                    p.LowerSlice();
                    p.SetOpaqueColor();
                }

                double distanceAwayX, distanceAwayY;

                
                // If there are pie slices
                for (int i = 0; i < pieSliceList.Count; i++)
                {
                    distanceAwayX = e.GetPosition(null).X;
                    distanceAwayY = e.GetPosition(null).Y;

                    Path p = pieSliceList[i].slicePath;
                    IEnumerable<UIElement> test = System.Windows.Media.VisualTreeHelper.FindElementsInHostCoordinates(new Point(distanceAwayX, distanceAwayY), p) as List<UIElement>;
                    //IEnumerable<UIElement> test = p.HitTest(new Point(distanceAwayX, distanceAwayY));

                    foreach (UIElement u in test)
                    {
                        if (u.GetType() == typeof(Path))
                        {
                            // Find out which path this is and then animate it to come out
                            for (int j = 0; j < pieSliceList.Count; j++)
                            {
                                if (((Path)u).Equals(pieSliceList[j].slicePath) &&
                                    pieSliceList[j].Fund.FundType == fundType &&
                                    pieSliceList[j].MissingFund == true)
                                {
                                    //pieSliceList[j].SetHighlightColor();
                                    pieSliceList[j].LiftSlice();
                                    
                                    isOverlapSlice = true;
                                    overlapSliceId = i;
                                    return true;
                                }
                            }
                        }
                    }
                }

                return false;
            }

            public void ColorSlicesOpaque()
            {
                for (int i = 0; i < pieSliceList.Count; i++)
                {
                    pieSliceList[i].SetOpaqueColor();
                }
            }

        #endregion

        #region Event Handlers
            
        #endregion

        #region Events

        #endregion

    }
}
